from fastapi import FastAPI, Request, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError
from contextlib import asynccontextmanager
import os

from app.database import sync_engine, Base
from app.routers import auth, users, files, unit_view
from app.middleware.response_formatter import ResponseFormatterMiddleware
from app.utils.config import settings
from app.utils.offline_docs import setup_offline_docs
from app.utils.offline_docs import setup_offline_docs


@asynccontextmanager
async def lifespan(app: FastAPI):
    """应用生命周期管理"""
    # 启动时创建数据库表
    Base.metadata.create_all(bind=sync_engine)

    yield

    # 关闭时清理资源
    sync_engine.dispose()


# 创建 FastAPI 应用实例
app = FastAPI(
    title="Demo Backend API",
    description="基于 FastAPI 的后端管理系统",
    version="1.0.0",
    docs_url=None,  # 禁用默认的docs路由
    redoc_url=None,  # 禁用默认的redoc路由
    lifespan=lifespan,
)

# 配置 CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=settings.ALLOWED_HOSTS,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 添加响应格式化中间件
app.add_middleware(ResponseFormatterMiddleware)

# 设置离线文档
setup_offline_docs(app)


# 全局异常处理器
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
    """处理请求验证错误"""
    return JSONResponse(
        status_code=422,
        content={
            "code": 422,
            "message": "请求参数验证失败",
            "data": {"detail": exc.errors(), "body": exc.body},
        },
    )


@app.exception_handler(HTTPException)
async def http_exception_handler(request: Request, exc: HTTPException):
    """处理HTTP异常"""
    return JSONResponse(
        status_code=exc.status_code,
        content={"code": exc.status_code, "message": exc.detail, "data": None},
    )


@app.exception_handler(Exception)
async def general_exception_handler(request: Request, exc: Exception):
    """处理其他未捕获的异常"""
    return JSONResponse(
        status_code=500,
        content={"code": 500, "message": "服务器内部错误", "data": None},
    )


# 配置静态文件服务
if not os.path.exists("uploads"):
    os.makedirs("uploads")

app.mount("/uploads", StaticFiles(directory="uploads"), name="uploads")

# 注册路由
app.include_router(auth.router, prefix="/api/auth", tags=["认证"])
app.include_router(users.router, prefix="/api/users", tags=["用户管理"])
app.include_router(files.router, prefix="/api/files", tags=["文件管理"])
app.include_router(unit_view.router, prefix="/api/unit_view", tags=["设备视图管理"])


@app.get("/")
async def root():
    """根路径"""
    return {"message": "欢迎使用 Demo Backend API", "docs": "/docs", "version": "1.0.0"}


@app.get("/health")
async def health_check():
    """健康检查"""
    return {"status": "ok", "message": "服务运行正常"}


if __name__ == "__main__":
    import uvicorn

    uvicorn.run(
        "main:app",
        host=settings.HOST,
        port=settings.PORT,
        reload=settings.DEBUG,
        log_level="info",
    )
